#include <QFileInfo>

#include "serverwidget.h"

#include "update/agreementmsg.h"


//发送文件数据包
typedef struct
{
  Base 	BaseFiles;
  quint32 fileLen;              //文件长度
  quint32 pkgCount;             //文件总包数
  quint32 pkgNum;               //当前包号
  quint32 pkgSize;              //数据包长度
  quint32 checkSum;             //校验位
//  char  fileName[48];           //文件名
//  char    pkg[PKGSIZE_SIZE];    //文件数据
//  quint64 position;             //位置
} tests;


ServerWidget::ServerWidget(int state, QWidget *parent)
    : QDialog(parent), serviceState(state)
{

    this->resize(800, 480);
    init();
    this->hide();
}

ServerWidget::~ServerWidget()
{
    tcpServer->closeClient();
    tcpServer->close();
    delete tcpServer;
    m_serialCtlThread->exit();

#ifdef _TTY_POSIX_
    m_examThread->close();
//    m_examThread->wait(400);
    m_examThread->exit();
//     delete m_examThread;
#endif
}


void ServerWidget::init()
{
    dogTimer = new QTimer(this);
    connect(dogTimer, SIGNAL(timeout()), this, SLOT(dogTimeOut()));
    isUpdateSuccess = false;

    m_serialCtlThread = new SerialCtlThread(this);
    connect(m_serialCtlThread, SIGNAL(sendVideoStatus(QList<LCDSTATUS>,bool)), this, SIGNAL(sendVideoStatus(QList<LCDSTATUS>,bool)));

    tcpServer = new TcpServer(serviceState, this);
    connect(tcpServer, SIGNAL(receFeedData(FreedDogStruct)),    this, SLOT(receFeedData(FreedDogStruct)));
    connect(tcpServer, SIGNAL(updateService(int,int)),          this, SLOT(receUpdateFile(int,int)));


    connect(tcpServer, SIGNAL(sendDebugMsg(QString)),           this, SLOT(receDubMsg(QString)));
    connect(tcpServer, SIGNAL(updateConfig()),                  this, SIGNAL(updateConfig()));
    connect(tcpServer, SIGNAL(receCheckLcdCmd(qint8)),          this, SIGNAL(receCheckLcdCmd(qint8)));

    connect(&closeTimer, SIGNAL(timeout()),                     this, SLOT(closeWidget()));

//    connect(tcpServer, SIGNAL(receGetLcdStateCmd()), serialCtl, SLOT(checkLcdState()));
//    connect(tcpServer, SIGNAL(receSetLcdSettingsCmd(LcdSettingStruct)), serialCtl, SLOT(setLcdSettings(LcdSettingStruct)));

    connect(tcpServer, SIGNAL(receGetLcdStatus()),                              m_serialCtlThread, SIGNAL(receGetLcdStatus()));
    connect(tcpServer, SIGNAL(receLcdBackLightCtl(qint8,QList<quint16>)),       m_serialCtlThread, SIGNAL(receLcdBackLightCtl(qint8,QList<quint16>)));

    connect(tcpServer, SIGNAL(receQueryVideoStatus(qint8)),                     m_serialCtlThread, SIGNAL(receQueryVideoStatus(qint8)));
    connect(tcpServer, SIGNAL(receSlcdCollectState(QList<PanelInfoStruct>)),    m_serialCtlThread, SIGNAL(receSlcdCollectState(QList<PanelInfoStruct>)));

    connect(tcpServer, SIGNAL(receChangeBriLv(LcdSettingStruct)),               m_serialCtlThread, SIGNAL(receChangeBriLv(LcdSettingStruct)));
    connect(tcpServer, SIGNAL(receChangeLcdBright(qint16,QList<quint16>)),      m_serialCtlThread, SIGNAL(receChangeLcdBright(qint16,QList<quint16>)));
    connect(tcpServer, SIGNAL(getLcdSetting()),                                 m_serialCtlThread, SIGNAL(getLcdSetting()));
    connect(tcpServer, SIGNAL(updateConfig()),                                  m_serialCtlThread, SIGNAL(updateConfig()));

//    connect(m_serialCtlThread, SIGNAL(sendSensorData(qint16)),              this, SLOT(receSensorData(qint16)));
    connect(m_serialCtlThread, SIGNAL(sendSensorData(qint16)),              tcpServer, SIGNAL(sendBrihgtness(qint16)));
    connect(m_serialCtlThread, SIGNAL(sendLcdSetting(LcdSettingStruct)),    tcpServer, SIGNAL(sendLcdSetting(LcdSettingStruct)));
    connect(m_serialCtlThread, SIGNAL(sendSetLcdSettingStatus(qint8)),      tcpServer, SIGNAL(sendSetLcdSettingStatus(qint8)));
    connect(m_serialCtlThread, SIGNAL(sendSetLcdTraValueStatus(qint8)),     tcpServer, SIGNAL(sendSetLcdTraValueStatus(qint8)));

    connect(m_serialCtlThread, SIGNAL(sendBackLightStatus(qint8)),          tcpServer, SIGNAL(sendBackLightStatus(qint8)));
    connect(m_serialCtlThread, SIGNAL(sendVideoStatus(QList<LCDSTATUS>,bool)),  tcpServer, SIGNAL(sendVideoStatus(QList<LCDSTATUS>,bool)));


    connect(m_serialCtlThread, SIGNAL(lcdAnswerStatus(QList<LCDSTATUS>)),   tcpServer, SIGNAL(lcdAnswerStatus(QList<LCDSTATUS>)));

    closeTimer.setSingleShot(true);

    int port = configClass.getConfigPort().toInt();

#ifdef _TTY_POSIX_
    m_examThread = new ExaminitionThread(this);
    m_examThread->start();
    connect(m_examThread, SIGNAL(systemState(SystemState)),     tcpServer,      SIGNAL(receSystemState(SystemState)));
    connect(tcpServer,    SIGNAL(getLcdSetting()),              m_examThread,   SLOT(appCheckSysState()));
    connect(tcpServer,    SIGNAL(clientConIn()),                m_examThread,   SLOT(appCheckSysState()));
    connect(m_serialCtlThread,    SIGNAL(sendLcdSetting(LcdSettingStruct)),     m_examThread,  SLOT(appCheckSysState()));
#endif

    if (!tcpServer->listen(QHostAddress::Any, port))
    {
        logger()->error("Fail to open the port:%1 communication with Maintenance Terminal\n", port);
    } else {
        logger()->info("Success to open the port:%1 communication with Maintenance Terminal\n", port);
    }

    manageProcess = new ManageProcess(this);
    m_serialCtlThread->start();

//    serialCtl->sendSyncCommand(20);
}

//这个函数用来控制显示控制器进程的
//如果服务端第一次运行，则把显示控制器启动，如果是升级后的话，则设置显示控制器的路径和参数
//等过到一定的时间之后没有收到显示控制器发过来的喂狗数据之后它才将显示控制器启动
void ServerWidget::startDisplayClient()
{
    QStringList arguments;

    QString msg;
    if (serviceState == 0)
    {
        manageProcess->startDisCtl(g_installPath + "/" + PROGRAMNAME, arguments);
    } else {
        manageProcess->setDisCtl(g_installPath + "/" + PROGRAMNAME, arguments);
    }
}

void ServerWidget::closeEvent(QCloseEvent *e)
{
    this->hide();
    tcpServer->closeClient();
    QWidget::closeEvent(e);
}

void ServerWidget::receFeedData(const FreedDogStruct& freedDogStruct)
{
    manageProcess->reSetTime();
}

void ServerWidget::receUpdateFile(const int state, const int fileCount)
{
    UpdateServer *updateServer = new UpdateServer(this);
    connect(updateServer, SIGNAL(receUpdateState(int)), this, SLOT(receUpdateStateSlot(int)));
    updateServer->listen(configClass.getUpdatePort().toInt());
    return;

    if (state >= 0)
    {
        if (state == 0)
        {
//            qDebug() << "start to update===============>>";
        } else {

            QString backupPath = g_installPath + "/" + BACKUPDATAPATH;
            QString updatePath = tr("%1/%2").arg(g_installPath).arg(UPDATEPATH);

            QString testPath = g_installPath + "/update/test";
            manageProcess->updateService(testPath, backupPath, updatePath);
            manageProcess->closeParentWidget((QWidget *)this->parent());
        }
    }
}

void ServerWidget::receDubMsg(const QString& msg)
{
//    textEdit->append("\n");
//    textEdit->append(msg);
}

void ServerWidget::dogTimeOut()
{
    QStringList arguments;
    manageProcess->startDisCtl(g_installPath + "/" + PROGRAMNAME, arguments);
//    dogTimer->stop();
}

void ServerWidget::receSensorData(const qint16 brightness)
{
//    QString msg = tr("rece brightness------------>%1").arg(brightness);
//    textEdit->append("\n");
//    textEdit->append(msg);
}

void ServerWidget::receSysState(const SystemState sysState)
{
//    qDebug() << "sysState===>" << "cpu:" << sysState.cpuOccRate << "mem:" << sysState.memOccRate << "hardDisk:" << sysState.hardDiskOccRate;
    tcpServer->setSystemState(sysState);
    emit systemState(sysState);
}

void ServerWidget::closeWidget()
{
    if (closeTimer.isActive())
    {
        closeTimer.stop();
    }
    event->accept();
    QWidget::closeEvent(event);
}

void ServerWidget::checkVidoStatu()
{
//    serialCtl->sendSyncCommand(20);
//    serialCtl->checkSLCDStatus();
    m_serialCtlThread->tisSelfTest();
}

void ServerWidget::receUpdateStateSlot(const int state)
{

    if (state >= 0)
    {
        if (state == 0)
        {
//            qDebug() << "start to update===============>>";
        } else {
            //3个参数，1，程序路径 2，更新文件路径 3，保存副本路径

            QString pgmPath = g_installPath;
            QString updatePath = g_installPath + "/" + UPDATEPATH;
            QString backupPath = g_installPath + "/" + BACKUPDATAPATH;
            manageProcess->updateService(pgmPath, updatePath, backupPath);
            manageProcess->closeParentWidget((QWidget *)this->parent());
        }
    } else {
//        qDebug() << "update success fail =========";
    }

}
